<?php
/**
 * FastApp.
 * 10/9/24
 * @Author deepsea159
 * @Contact telegram:deepsea159
 */

namespace App\Game\Corncob;

use App\Fastapp\Model\AccountInviteLevel;
use App\Fastapp\Model\FastappAppSetting;
use App\Game\Model\GameBet;
use App\Game\Model\GameProfit;
use Carbon\Carbon;
use Hyperf\Crontab\Annotation\Crontab;

class BetCorncob
{
    #[Crontab(name: "BetUserCorncob", rule: "5 0 * * *", memo: "用户有效投注奖励")]
    public function user(): void
    {
        $settings = FastappAppSetting::query()
            ->where('account_type', 'like', '70%')
            ->whereIn('key', ['working_profit_interval', 'working_bet_amount', 'working_bet_0_rate', 'working_bet_1_rate', 'working_bet_2_rate'])
            ->get()->mapToGroups(function ($item) {
                return [$item->account_type => $item];
            });
        foreach ($settings as $ac_type => $item) {
            $setting = $item->pluck('val', 'key')->toArray();
            $k = 'game:bcu:' . $ac_type;
            $date = redis()->get($k);
            if (!$date) {
                redis()->set($k, Carbon::now()->subDay()->toDateString());
                continue;
            }
            $dif = Carbon::now()->diffInDays(Carbon::createFromFormat('Y-m-d', $date));
            if ($dif < $setting['working_profit_interval']) continue;
            $start_at = $date . ' 00:00:00';
            $end_at = Carbon::now()->toDateString() . ' 00:00:00';
            $res = GameBet::query()->selectRaw('user_id,sum(amount) as amount')->from('game_bet as a')
                ->join('account as b', 'b.gene_id', '=', 'a.user_id')
                ->where(['a.status' => 1, 'b.type' => $ac_type])->whereBetween('a.created_at', [$start_at, $end_at])
                ->groupBy('user_id')->get();

            $uids = $res->pluck('user_id')->toArray();
            $pids = AccountInviteLevel::query()->whereIn('user_id', $uids)->get()->mapToGroups(function ($item) {
                return [$item->parent_id => $item->user_id];
            })->toArray();
            $ppids = AccountInviteLevel::query()->whereIn('user_id', array_keys($pids))->get()->mapToGroups(function ($item) {
                return [$item->parent_id => $item->user_id];
            })->toArray();
            $am = $res->pluck('amount', 'user_id')->toArray();
            $uam = [];
            foreach ($am as $uid => $amount) {
                foreach ($pids as $pid => $children) {
                    if (!isset($uam[$pid][1])) $uam[$pid][1] = '0';
                    if (in_array($uid, $children)) $uam[$pid][1] = bcadd($uam[$pid][1], $amount, 2);
                }
            }
            foreach ($pids as $pid => $children) {
                foreach ($ppids as $ppid => $ch) if (in_array($pid, $ch)) $uam[$ppid][2] = $uam[$pid][1];
            }
            $profit = [];
            foreach ($uam as $uid => $v) {
                $profit[$uid] = '0';
                if (isset($v[1])) {
                    if (bccomp($v[1], $setting['working_bet_amount']) == -1) {
                        $profit[$uid] = bcmul($v[1], bcdiv($setting['working_bet_0_rate'], '100', 4), 2);
                    } else {
                        $profit[$uid] = bcmul($v[1], bcdiv($setting['working_bet_1_rate'], '100', 4), 2);
                    }
                }
                if (isset($v[2])) {
                    if (bccomp($v[2], $setting['working_bet_amount']) == -1) {
                        $profit[$uid] = bcadd($profit[$uid], bcmul($v[2], bcdiv($setting['working_bet_0_rate'], '100', 4), 2), 2);
                    } else {
                        $profit[$uid] = bcadd($profit[$uid], bcmul($v[2], bcdiv($setting['working_bet_2_rate'], '100', 4), 2), 2);
                    }
                }
            }
            $in = [];
            foreach ($profit as $uid => $v) {
                $in[] = [
                    'user_id' => $uid,
                    'amount' => $v,
                    'start_at' => substr($start_at, 0, 10),
                    'end_at' => substr($end_at, 0, 10),
                ];
            }
            if ($in) GameProfit::query()->insert($in);
            redis()->set($k, Carbon::now()->toDateString());
        }
    }
}